package com.guducat.collegeWeb.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.util.SaResult;
import com.guducat.collegeWeb.dto.response.FileUploadResultDTO;
import com.guducat.collegeWeb.service.FileUploadService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件上传控制器
 * 提供文件上传功能，需要管理员权限
 */
@Slf4j
@RestController
@RequestMapping("/api/admin/upload")
@Tag(name = "文件上传管理", description = "提供文件上传功能，需要管理员权限")
public class FileUploadController {

    private final FileUploadService fileUploadService;

    @Autowired
    public FileUploadController(FileUploadService fileUploadService) {
        this.fileUploadService = fileUploadService;
    }

    /**
     * 上传图片文件
     * @param file 上传的图片文件
     * @return 上传结果，包含图片访问URL
     */
    @Operation(
            summary = "上传图片",
            description = "上传图片文件到MinIO对象存储，支持JPEG、PNG、GIF、WebP、BMP格式，最大5MB。需要管理员权限。",
            security = { @SecurityRequirement(name = "satoken") }
    )
    @ApiResponses({
            @ApiResponse(
                    responseCode = "200",
                    description = "图片上传成功",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = SaResult.class)
                    )
            ),
            @ApiResponse(responseCode = "400", description = "请求参数错误或文件格式不支持"),
            @ApiResponse(responseCode = "401", description = "未登录"),
            @ApiResponse(responseCode = "403", description = "无管理员权限"),
            @ApiResponse(responseCode = "413", description = "文件大小超过限制"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    @PostMapping(value = "/image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @SaCheckLogin
    // 临时允许有编辑权限的用户上传图片，而不仅仅是Admin
    // @SaCheckPermission("Admin")
    public Object uploadImage(
            @Parameter(
                    description = "要上传的图片文件",
                    required = true,
                    content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA_VALUE)
            )
            @RequestParam("file") MultipartFile file) {

        try {
            log.info("开始上传图片文件: {}, 大小: {} bytes",
                    file.getOriginalFilename(), file.getSize());

            // 调用服务层上传文件
            FileUploadResultDTO result = fileUploadService.uploadImage(file);

            log.info("图片上传成功: {}", result.getUrl());

            // 返回wangEditor期望的格式
            var response = new java.util.HashMap<String, Object>();
            response.put("errno", 0);

            var data = new java.util.HashMap<String, Object>();
            data.put("url", result.getUrl());
            data.put("alt", result.getAlt());
            data.put("href", result.getHref());
            response.put("data", data);

            return response;

        } catch (IllegalArgumentException e) {
            // 参数验证错误
            log.warn("图片上传参数错误: {}", e.getMessage());

            var errorResponse = new java.util.HashMap<String, Object>();
            errorResponse.put("errno", 1);
            errorResponse.put("message", e.getMessage());
            return errorResponse;

        } catch (Exception e) {
            // 其他错误
            log.error("图片上传失败: {}", e.getMessage(), e);

            var errorResponse = new java.util.HashMap<String, Object>();
            errorResponse.put("errno", 1);
            errorResponse.put("message", "图片上传失败，请稍后再试");
            return errorResponse;
        }
    }

    /**
     * 删除文件
     * @param objectName 对象名（文件路径）
     * @return 删除结果
     */
    @Operation(
            summary = "删除文件",
            description = "从MinIO对象存储中删除指定文件。需要管理员权限。",
            security = { @SecurityRequirement(name = "satoken") }
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "文件删除成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "401", description = "未登录"),
            @ApiResponse(responseCode = "403", description = "无管理员权限"),
            @ApiResponse(responseCode = "404", description = "文件不存在"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    @DeleteMapping("/file")
    @SaCheckLogin
    @SaCheckPermission("Admin")
    public SaResult deleteFile(
            @Parameter(description = "要删除的文件对象名", required = true, example = "images/20241201_123456_abc12345.jpg")
            @RequestParam("objectName") String objectName) {

        try {
            if (objectName == null || objectName.trim().isEmpty()) {
                return SaResult.error("文件对象名不能为空");
            }

            log.info("开始删除文件: {}", objectName);

            // 调用服务层删除文件
            fileUploadService.deleteFile(objectName);

            log.info("文件删除成功: {}", objectName);

            return SaResult.ok("文件删除成功");

        } catch (Exception e) {
            log.error("文件删除失败: {}", e.getMessage(), e);
            return SaResult.error("文件删除失败，请稍后再试");
        }
    }

    /**
     * 获取文件上传配置信息
     * @return 上传配置信息
     */
    @Operation(
            summary = "获取上传配置",
            description = "获取文件上传的配置信息，如最大文件大小、支持的文件类型等。需要管理员权限。",
            security = { @SecurityRequirement(name = "satoken") }
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "获取配置成功"),
            @ApiResponse(responseCode = "401", description = "未登录"),
            @ApiResponse(responseCode = "403", description = "无管理员权限")
    })
    @GetMapping("/config")
    @SaCheckLogin
    @SaCheckPermission("Admin")
    public SaResult getUploadConfig() {
        try {
            // 构建配置信息
            var config = new java.util.HashMap<String, Object>();
            config.put("maxFileSize", 5 * 1024 * 1024); // 5MB
            config.put("allowedTypes", java.util.Arrays.asList(
                    "image/jpeg", "image/jpg", "image/png", "image/gif", "image/webp", "image/bmp"
            ));
            config.put("allowedExtensions", java.util.Arrays.asList(
                    "jpg", "jpeg", "png", "gif", "webp", "bmp"
            ));

            return SaResult.data(config);

        } catch (Exception e) {
            log.error("获取上传配置失败: {}", e.getMessage(), e);
            return SaResult.error("获取配置失败");
        }
    }
}
